<?php
namespace ScarecrowCache\lib\interfaces;

abstract class DbHandleAbstract{
	//数据文件地址
	private $dataFilePath = __DIR__ . '/../../data/';

	//数据文件名称
	private $dbDataFileName = 'ScarecrowDat.dat';

	//数据索引文件名称
	private $dbIdxFileName = 'ScarecrowIdx.idx';

	//数据文件操作句柄
	protected $dbDataHandle = NULL;

	//索引文件操作句柄
	protected $dbIdxHandle = NULL;

	//文件是否关闭
	protected $isClose = true;

	private $isDubug = false;

	public function __construct($isDebug = true)
	{
		require_once __DIR__ . '/../allConstList.php';
		$this->isDubug = $isDebug;

	}

	/**
	 * 显示调试信息
	 * @param $str
	 */
	protected function showDebug($str)
	{
		if ($this->isDubug) {
			var_dump($str);
		}
	}

	/**
	 * 打开文件
	 * @return bool
	 */
	protected function openDbFile()
	{
		if ($this->dbDataHandle !== NULL && $this->dbDataHandle !== false && $this->dbIdxHandle !== NULL && $this->dbIdxHandle !== false) {
			return S_DB_SUCCESS;
		} else {
			$init = false;
			if (!file_exists($this->dataFilePath . $this->dbIdxFileName)) {
				$init = true;

				$this->dbDataHandle = fopen($this->dataFilePath . $this->dbDataFileName , 'wb+');
				$this->dbIdxHandle = fopen($this->dataFilePath . $this->dbIdxFileName, 'wb+');
			} else {
				$this->dbDataHandle = fopen($this->dataFilePath . $this->dbDataFileName , 'rb+');
				$this->dbIdxHandle = fopen($this->dataFilePath . $this->dbIdxFileName, 'rb+');
			}

			if ($this->dbIdxHandle && $this->dbDataHandle) {
				if ($init) {
					$elem = pack('L', 0x00000000);
					for ($i=0; $i < S_DB_BUCKET_SIZE; $i++) {
						fwrite($this->dbIdxHandle, $elem, 4);
					}
				}
				$this->isClose = false;
				rewind($this->dbIdxHandle);
				rewind($this->dbDataHandle);
				return S_DB_SUCCESS;
			} else {
				$this->dbIdxHandle = NULL;
				$this->dbDataHandle = NULL;
				$this->showDebug("数据文件与索引文件打开失败！");
				return S_DB_FAIL;
			}
		}
	}

	/**
	 * 关闭文件
	 */
	protected function closeDbFile()
	{
		if ($this->dbIdxHandle) {
			@fclose($this->dbIdxHandle);
			$this->showDebug('索引文件已关闭');
		}

		if ($this->dbDataHandle) {
			@fclose($this->dbDataHandle);
			$this->showDebug('数据文件已关闭');
		}

		$this->dbIdxHandle = NULL;
		$this->dbDataHandle = NULL;
		$this->isClose = true;
	}

	/**
	 * 删除所有缓存
	 */
	public function deleteAllCache()
	{
		$this->closeDbFile();
		if (file_exists($this->dataFilePath . $this->dbIdxFileName)) {
			@unlink($this->dataFilePath . $this->dbIdxFileName);
		}

		if (file_exists($this->dataFilePath . $this->dbDataFileName)) {
			@unlink($this->dataFilePath . $this->dbDataFileName);
		}
	}

	/**
	 * 取Hash值
	 * @param $str
	 * @return int
	 */
	protected function hashMap($str)
	{
		$hash = 5381;
		$str    = md5($str);
		$seed = 5;
		$len  = 32;
		for ($i = 0; $i < $len; $i++) {
			$hash = ($hash << $seed) + $hash + ord($str{$i});
		}
		return $hash & 0x7FFFFFFF;
	}

	public function __destruct()
	{
		// TODO: Implement __destruct() method.
		$this->closeDbFile();
	}

	/**
	 * 添加一条记录
	 * @param $key
	 * @param $value
	 * @param $flag
	 * @return mixed
	 */
	abstract public function insert(string $key, $value, $flag = S_DB_STORE);

	/**
	 * 获取一条数据
	 * @param string $key
	 * @return mixed
	 */
	abstract public function fetch(string $key, $default=null);

	/**
	 * 删除一条数据
	 * @param string $key
	 * @return mixed
	 */
	abstract public function delete(string $key);

}